package cn.bailin233.system.controller;

import cn.bailin233.system.entity.user.User;
import cn.bailin233.system.service.UserService;
import cn.bailin233.web.utils.ResultUtil;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.stp.StpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 登录控制器
 */
@RestController
@RequestMapping("/myWeb")
public class LoginController {

    // OAuth2 地址
    private String uri = "http://localhost:8888";

    // 客户端id
    private String clientId = "1004";
    // 客户端密钥
    private String clientSecret = "aaaa-bbbb-cccc-dddd-eeee";
    // 请求授权类型
    private String responseType = "code";
    // 重定向地址
    private String redirectUri = "http://localhost:9900/system/myWeb/getAccessToken?redirectUri=http://localhost:8080/login/doLogin";
    // 客户端权限
    private String scope = "all";
    // 授权类型
    private String grantType = "authorization_code";

    @Autowired
    UserService userService;

    // 查询是否登录
    @GetMapping("/isLogin")
    public ResultUtil isLogin() {
        if (StpUtil.isLogin()) {
            return ResultUtil.success("已登录");
        } else {
            return ResultUtil.error("未登录");
        }
    }

    // 账号密码登录
    @GetMapping("/doLogin")
    public ResultUtil doLogin(String name, String pwd) {
        Long uid = userService.doLogin(name, pwd);
        if (uid == null) return ResultUtil.error("账号或密码错误");
        StpUtil.login(uid);
        return ResultUtil.success("登录成功", StpUtil.getTokenInfo());
    }

    // 第三方登录， 获取授权码
    @GetMapping("/getCode")
    public void getCode(HttpServletResponse response) throws IOException {
        String url = uri + "/oauth2/authorize" +
                "?response_type=" + responseType +
                "&client_id=" + clientId +
                "&redirect_uri=" + redirectUri +
                "&scope=" + scope;
        response.sendRedirect(url);
    }

    // 第三方登录，获取access_token，存入Rides
    @GetMapping("/getAccessToken")
    public void getAccessToken(String redirectUri, String code, HttpServletResponse response) throws IOException {
        // client_secret需从数据库里查
        String url = uri + "/oauth2/token" +
                "?grant_type=" + grantType +
                "&client_id=" + clientId +
                "&client_secret=" + clientSecret +
                "&code=" + code;
        RestTemplate restTemplate = new RestTemplate();
        // 请求login-service OAuth2服务 获取accessToken
        ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
        JSONObject bodyJson = JSON.parseObject(forEntity.getBody());
        // 在第三方查询第三方的账号，进行自己的登录逻辑
        JSONObject data = (JSONObject) bodyJson.get("data");
        String accessToken = (String) data.get("access_token");
        int resultCode;
        String oauthName = null;
        String params;
        if (accessToken != null) {
            url = uri + "/user/getName";
            // 请求login-service OAuth2服务 获取账号
            forEntity = restTemplate.getForEntity(url + "?access_token=" + accessToken, String.class);
            bodyJson = JSON.parseObject(forEntity.getBody());
            if ((int) bodyJson.get("code") == 200) {
                oauthName = (String) bodyJson.get("data");
                Long uid = userService.loginInOauthName(oauthName);
                if (uid != null) {
                    StpUtil.login(uid);
                    userService.insertAccessToken(uid, accessToken);
                    resultCode = 200;
                } else {
                    System.out.println("oauth2账号未绑定" + oauthName);
                    resultCode = 100;
                }
            } else {
                System.out.println("accessToken无效" + accessToken);
                resultCode = 150;
            }
        } else {
            System.out.println("无accessToken");
            resultCode = 170;
        }
        params = "?code=" + resultCode;
        if (resultCode == 100 && oauthName != null) params += "&oauthName=" + oauthName;
        response.sendRedirect(redirectUri + params);
    }

    // 注册账号
    @PostMapping("/singIn")
    public ResultUtil singIn(String name, String pwd) {
        if (name == null || pwd == null || name.equals("") || pwd.equals("")) return ResultUtil.error("账号或密码错误");
        User user = new User();
        user.setAccount(name);
        user.setPassword(pwd);
        switch (userService.insertOne(user)) {
            case -1:
                return ResultUtil.error("账号已存在");
            case 1:
                return ResultUtil.success("注册成功", null);
            default:
                return ResultUtil.error("系统未知错误！");
        }
    }

    // 账号绑定
    @PostMapping("/binDing")
    public ResultUtil binDing(String oauthName) throws NotLoginException {
        Long uid = StpUtil.getLoginIdAsLong();
        switch (userService.binDing(uid, oauthName)) {
            case -1:
                return ResultUtil.error("该账号以绑定！");
            case 1:
                return ResultUtil.success("绑定成功", null);
            default:
                return ResultUtil.error("系统未知错误！");
        }
    }

}

